home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1997 April / EnigmA AMIGA RUN 17 (1997)(G.R. Edizioni)(IT)[!][issue 1997-04][EAR-CD].iso / EARCD / util / wb / lupe.lha / source / lupe.c < prev    next >
C/C++ Source or Header  |  1996-11-18  |  62KB  |  2,351 lines

  1. // Lupe V1.7 - 1995-96 - © Frank Toepper
  2. // a lens
  3. // AmigaOS 3.0+
  4. // Maxon C++ V3
  5. // last changes: 23.October.96
  6.  
  7. #include <string.h>
  8. #include <iostream.h>
  9. extern "C"
  10. {
  11. #include <clib/alib_protos.h>
  12. }
  13. #include <intuition/intuition.h>
  14. #include <intuition/imageclass.h>
  15. #include <intuition/icclass.h>
  16. #include <intuition/gadgetclass.h>
  17. #include <intuition/intuitionbase.h>
  18. #include <exec/exec.h>
  19. #include <dos/dos.h>
  20. #include <graphics/scale.h>
  21. #include <devices/inputevent.h>
  22. #include <libraries/commodities.h>
  23. #include <libraries/gadtools.h>
  24. #include <datatypes/pictureclass.h>
  25. #include <graphics/displayinfo.h>
  26. #include <graphics/gfxmacros.h>
  27. #include <graphics/gfxbase.h>
  28. #include <cybergraphics/cybergraphics.h>
  29. #include <clib/dos_protos.h>
  30. #include <pragma/dos_lib.h>
  31. #include <clib/intuition_protos.h>
  32. #include <pragma/intuition_lib.h>
  33. #include <clib/graphics_protos.h>
  34. #include <pragma/graphics_lib.h>
  35. #include <clib/exec_protos.h>
  36. #include <pragma/exec_lib.h>
  37. #include <clib/commodities_protos.h>
  38. #include <pragma/commodities_lib.h>
  39. #include <clib/gadtools_protos.h>
  40. #include <pragma/gadtools_lib.h>
  41. #include <clib/icon_protos.h>
  42. #include <pragma/icon_lib.h>
  43. #include <clib/cybergraphics_protos.h>
  44. #include <pragma/cybergraphics_lib.h>
  45. #include <clib/wb_protos.h>
  46. #include <pragma/wb_lib.h>
  47. #include <libraries/asl.h>
  48. #include <clib/asl_protos.h>
  49. #include <pragma/asl_lib.h>
  50. #include <wbstartup.h>
  51.  
  52. #pragma header
  53.  
  54. #define VERSION "Lupe V1.7"
  55.  
  56. #define CYBERARRAY_BPP 3
  57. #define MINWIDTH 56
  58. #define MINHEIGHT 30
  59.  
  60. UWORD innerwidth = 150, innerheight = 100, sourcewidth, sourceheight;
  61. UWORD scalefac = 5, maxscalefac = 15, minwidth, fixedX = 0, fixedY = 0;
  62. UWORD leftoff, topoff, bottomoff, rightoff;
  63. UWORD sizeiw, sizeih, winx, winy, winleft = 0, wintop = 11, originX = 0, originY = 0;
  64. UWORD textoff, coordsstringlen, fontX, fontY, oldx, oldy, scrdepth;
  65. ULONG cxsigflag, waitmask = 0, pens[6];
  66. APTR VisualInfo, cyberdata = NULL;
  67. BPTR fh;
  68. struct MsgPort *broker_mp, *userport, *app_mp = NULL;
  69. struct Task *thistask;
  70. struct Window *mywin;
  71. struct Screen *scr = NULL, *tmpscr;
  72. struct Menu *menu = NULL;
  73. struct MenuItem *item;
  74. struct BitMap *srcbm = NULL, *destbm = NULL, *scrbm, *maskbm = NULL;
  75. struct TextFont *screenfont = NULL, *topazfont;
  76. struct InputXpression setoriginix, resetoriginix, showhideix;
  77. struct RastPort *scrrp, destrp, *winrp, maskrp;
  78. struct Library *CxBase, *GadToolsBase, *CyberGfxBase, *IconBase, *WorkbenchBase, *AslBase;
  79. struct GfxBase *GfxBase;
  80. struct AppIcon *appicon = NULL;
  81. struct AppMessage *appmsg;
  82. struct DiskObject *icon = NULL;
  83. UBYTE timesig, showhidesig;
  84. BOOL hires, newlook, jump = FALSE, fast = FALSE, pubscreenlocked = FALSE, enable = TRUE;
  85. BOOL cybergfxscreen, coords = FALSE, crosshair = FALSE, origin = TRUE, fixed = FALSE;
  86. BOOL jumpdirect, showhide = TRUE, hide = FALSE, hideonclose = FALSE, grid = FALSE, showrgb = FALSE;
  87. CxObj *broker, *customcxobj;
  88. Object *propgadget;
  89. char pubscreenname[MAXPUBSCREENNAME];
  90. char setoriginkey[50] = "lalt o", resetoriginkey[50] = "lalt r", showhidekey[50] = "lalt h";
  91. char title[10], dispstring[12];
  92. char programname[110], iffpath[256] = "ram:Lupe.iff", iffname[110];
  93. char *Template = "CX_PRIORITY=P/N/K, FAST=F/S/K, MAXSCALEFACTOR=M/N/K, SCALEFACTOR=S/N/K, "
  94.                  "WINLEFT=L/N/K, WINTOP=T/N/K, WINWIDTH=W/N/K, WINHEIGHT=H/N/K, "
  95.                  "COORDINATES=C/S/K, CROSSHAIR=R/S/K, SETORIGINKEY=O/K, RESETORIGINKEY=K/K, "
  96.                  "FIXED=D/S/K, SHOWHIDEKEY=SH/K, ICONIFY=I/S/K, ICONIFYONCLOSE=IOC/S/K, "
  97.                  "GRID=G/S/K, SHOWRGB=RGB/S/K, IFFFILE=IF/K";
  98.  
  99. extern struct IntuitionBase *IntuitionBase;
  100.  
  101. // function declarations for menu
  102. BOOL jumpFunc ();
  103. BOOL saveFunc ();
  104. BOOL fastFunc ();
  105. BOOL AboutFunc ();
  106. BOOL enableFunc ();
  107. BOOL coordsFunc ();
  108. BOOL crosshairFunc ();
  109. BOOL gridFunc ();
  110. BOOL showrgbFunc ();
  111. BOOL fixedFunc ();
  112. BOOL QuitFunc ();
  113. BOOL hideFunc ();
  114. BOOL hideoncloseFunc ();
  115.  
  116. struct NewMenu standartmenu[] = {
  117.   { NM_TITLE, "Project",            0, 0, 0, 0 },
  118.   {  NM_ITEM, "Jump",               "J", 0, 0, jumpFunc },
  119.   {  NM_ITEM, "Jump To Screen",     0, 0, 0, 0 },
  120.   {  NM_ITEM, NM_BARLABEL,          0, 0, 0, 0 },
  121.   {  NM_ITEM, "Save IFF...",        "S", 0, 0, saveFunc },
  122.   {  NM_ITEM, NM_BARLABEL,          0, 0, 0, 0 },
  123.   {  NM_ITEM, "Enable",             "E", CHECKIT | MENUTOGGLE, 0, enableFunc },
  124.   {  NM_ITEM, "Fixed",              "D", CHECKIT | MENUTOGGLE, 0, fixedFunc },
  125.   {  NM_ITEM, "Fast",               "F", CHECKIT | MENUTOGGLE, 0, fastFunc },
  126.   {  NM_ITEM, "Coordinates",        "C", CHECKIT | MENUTOGGLE, 0, coordsFunc },
  127.   {  NM_ITEM, "Crosshair",          "R", CHECKIT | MENUTOGGLE, 0, crosshairFunc },
  128.   {  NM_ITEM, "Grid",               "G", CHECKIT | MENUTOGGLE, 0, gridFunc },
  129.   {  NM_ITEM, "Show RGB",           "W", CHECKIT | MENUTOGGLE, 0, showrgbFunc },
  130.   {  NM_ITEM, NM_BARLABEL,          0, 0, 0, 0 },
  131.   {  NM_ITEM, "About",              "?", 0, 0, AboutFunc },
  132.   {  NM_ITEM, NM_BARLABEL,          0, 0, 0, 0 },
  133.   {  NM_ITEM, "Iconify On Close",   "N", CHECKIT | MENUTOGGLE, 0, hideoncloseFunc },
  134.   {  NM_ITEM, "Iconify",            "I", 0, 0, hideFunc },
  135.   {  NM_ITEM, "Quit",               "Q", 0, 0, QuitFunc },
  136.   {  NM_END, 0, 0, 0, 0, 0 }
  137. };
  138.  
  139. struct EasyStruct es_about = {
  140.    20, 0,
  141.    "Lupe",
  142.    "%s",
  143.    "%s"
  144. };
  145.  
  146. char *era_about[] = {
  147.    VERSION " (" __DATE__ ")\n\n"
  148.    "written by:\n"
  149.    "  Frank Toepper\n"
  150.    "  Maxim Gorki Straße 5A\n"
  151.    "  Greifswald\n"
  152.    "  17491\n"
  153.    "  GERMANY\n\n"
  154.    "E-Mail:\n"
  155.    "  toepper@rz.uni-greifswald.de\n"
  156.    "WWW:\n"
  157.    "  http://www.user.fh-stralsund.de/~rwermke/di.html\n\n"
  158.    "This program is Public Domain",
  159.    "Ok"
  160. };
  161.  
  162. struct NewBroker newbroker = {
  163.    NB_VERSION,
  164.    "Lupe",
  165.    VERSION " © 1995-96 Frank Toepper",
  166.    "A magnifying glass program.",
  167.    3,
  168.    COF_SHOW_HIDE,
  169.    0,
  170.    NULL,
  171.    0
  172. };
  173.  
  174. struct BitScaleArgs bsa = {
  175.    // Src Koords
  176.    0, 0,
  177.    innerwidth / scalefac,
  178.    innerheight / scalefac,
  179.    // Src Faktoren
  180.    1, 1,
  181.    0, 0,
  182.    innerwidth,
  183.    innerheight,
  184.    // Dest Faktoren
  185.    scalefac, scalefac,
  186.    // Bitmaps
  187.    NULL, NULL,
  188.    0,
  189.    0, 0,
  190.    0, 0
  191. };
  192.  
  193. struct TextAttr topaz_attr = {
  194.    "topaz.font",
  195.    8,
  196.    0,
  197.    FPF_ROMFONT
  198. };
  199.  
  200. void Putchar (register __d0 char zeichen, register __a3 char *putchdata)
  201. {
  202.    *putchdata++ = zeichen;
  203. }
  204.  
  205. void error (char *formatstring, ...)
  206. {
  207.  APTR args = &formatstring + 1;
  208.  struct EasyStruct easystruct = {
  209.     sizeof (struct EasyStruct),
  210.     0,
  211.     "Error",
  212.     formatstring,
  213.     "Ok"
  214.  };
  215.  
  216.    if (Cli ())
  217.    {
  218.       VPrintf (formatstring, (LONG *) args);
  219.       FPutC (Output (), '\n');
  220.       Flush (Output ());
  221.    }
  222.    else
  223.    {
  224.       EasyRequestArgs (NULL, &easystruct, NULL, args);
  225.    }
  226. }
  227.  
  228. BOOL lockaspublicscreen (struct Screen *screen)
  229. {
  230.  struct List *pubscreenlist;
  231.  struct PubScreenNode *pubscreennode;
  232.  
  233.    pubscreenlist = LockPubScreenList ();
  234.    if (pubscreenlist)
  235.    {
  236.       pubscreennode = (struct PubScreenNode *) pubscreenlist->lh_Head;
  237.       while (pubscreennode)
  238.       {
  239.          if (pubscreennode->psn_Screen == screen)
  240.          {
  241.             if (LockPubScreen (pubscreennode->psn_Node.ln_Name))
  242.             {
  243.                UnlockPubScreenList ();
  244.                return TRUE;
  245.             }
  246.          }
  247.          pubscreennode = (struct PubScreenNode *) pubscreennode->psn_Node.ln_Succ;
  248.       }
  249.       UnlockPubScreenList ();
  250.    }
  251.    return FALSE;
  252. }
  253.  
  254. int setupscreen (struct Screen *selectedscreen)
  255. {
  256.  ULONG id;
  257.  
  258.    jumpdirect = FALSE;
  259.    if (selectedscreen)
  260.    {
  261.       jumpdirect = TRUE;
  262.       if (scr)
  263.       {
  264.          if (VisualInfo)
  265.          {
  266.             FreeVisualInfo (VisualInfo);
  267.          }
  268.          if (pubscreenlocked)
  269.          {
  270.             UnlockPubScreen (NULL, scr);
  271.          }
  272.       }
  273.       if (lockaspublicscreen (selectedscreen))
  274.       {
  275.          pubscreenlocked = TRUE;
  276.       }
  277.       else
  278.       {
  279.          pubscreenlocked = FALSE;
  280.       }
  281.       scr = selectedscreen;
  282.    }
  283.    else if (scr)
  284.    {
  285.       tmpscr = scr->NextScreen;
  286.       if (tmpscr)
  287.       {
  288.          FreeVisualInfo (VisualInfo);
  289.          VisualInfo = NULL;
  290.          if (pubscreenlocked)
  291.          {
  292.             UnlockPubScreen (NULL, scr);
  293.             pubscreenlocked = FALSE;
  294.          }
  295.          if (lockaspublicscreen (tmpscr))
  296.          {
  297.             pubscreenlocked = TRUE;
  298.          }
  299.       }
  300.       else
  301.       {
  302.          error ("There is no other screen.");
  303.          return 1;  // not real an error
  304.       }
  305.       scr = tmpscr;
  306.    }
  307.    else if ((scr = LockPubScreen (NULL)) != 0)
  308.    {
  309.       pubscreenlocked = TRUE;
  310.    }
  311.    else
  312.    {
  313.       error ("Can't lock publicscreen.");
  314.       return 2;
  315.    }
  316.    VisualInfo = GetVisualInfoA (scr, NULL);
  317.    if (!VisualInfo)
  318.    {
  319.       error ("Can't get visualinfo from screen.");
  320.       return 3;
  321.    }
  322.    cybergfxscreen = FALSE;
  323.    if (CyberGfxBase)
  324.       if ((id = GetVPModeID (&scr->ViewPort)) != INVALID_ID)
  325.          if (IsCyberModeID (id))
  326.             if (GetCyberIDAttr (CYBRIDATTR_BPPIX, id) > 1)
  327.                cybergfxscreen = TRUE;
  328.    return 0;
  329. }
  330.  
  331. void CloseDownScreen ()
  332. {
  333.    if (VisualInfo)
  334.    {
  335.       FreeVisualInfo (VisualInfo);
  336.       VisualInfo = NULL;
  337.    }
  338.    if (scr && pubscreenlocked)
  339.    {
  340.       UnlockPubScreen (NULL, scr);
  341.       pubscreenlocked = FALSE;
  342.    }
  343. }
  344.  
  345. void getoffsets ()
  346. {
  347.  struct DrawInfo *drawinfo;
  348.  APTR sizeobject;
  349.  ULONG attr;
  350.  
  351.    if (screenfont)
  352.    {
  353.       CloseFont (screenfont);
  354.       screenfont = NULL;
  355.    }
  356.    hires = (scr->Flags & SCREENHIRES) != 0;
  357.    hires ? (rightoff = 18) : (rightoff = 13);
  358.    SetAPen (&maskrp, 1);
  359.    drawinfo = GetScreenDrawInfo (scr);
  360.    if (drawinfo)
  361.    {
  362.       sizeobject = NewObject (NULL, SYSICLASS,
  363.        SYSIA_Which, SIZEIMAGE, SYSIA_DrawInfo, drawinfo,
  364.        SYSIA_Size, hires ? SYSISIZE_MEDRES : SYSISIZE_LOWRES, TAG_END);
  365.       if (sizeobject)
  366.       {
  367.          if (GetAttr (IA_Width, sizeobject, &attr))
  368.          {
  369.             sizeiw = attr;
  370.             rightoff =  (UWORD) attr;
  371.          }
  372.          if (GetAttr (IA_Height, sizeobject, &attr))
  373.          {
  374.             sizeih = attr;
  375.          }
  376.          newlook = (drawinfo->dri_Flags & DRIF_NEWLOOK) && (drawinfo->dri_Depth != 1);
  377.          SetAPen (&maskrp, drawinfo->dri_Pens[SHADOWPEN]);
  378.          DisposeObject (sizeobject);
  379.       }
  380.       pens[0] = drawinfo->dri_Pens[FILLTEXTPEN];
  381.       pens[1] = drawinfo->dri_Pens[FILLPEN];
  382.       pens[2] = drawinfo->dri_Pens[TEXTPEN];
  383.       pens[3] = drawinfo->dri_Pens[BACKGROUNDPEN];
  384.       pens[4] = drawinfo->dri_Pens[SHINEPEN];
  385.       pens[5] = drawinfo->dri_Pens[SHADOWPEN];
  386.       FreeScreenDrawInfo (scr, drawinfo);
  387.    }
  388.    else
  389.    {
  390.       // default pens
  391.       pens[0] = 2;
  392.       pens[1] = 3;
  393.       pens[2] = 1;
  394.       pens[3] = 0;
  395.       pens[4] = 2;
  396.       pens[5] = 1;
  397.    }  // if (drawinfo)
  398.    scrrp = &scr->RastPort;
  399.    topoff = scrrp->TxHeight + (UWORD) scr->WBorTop + 1;
  400.    leftoff = scr->WBorLeft;
  401.    scrbm = scrrp->BitMap;
  402.    scrdepth = GetBitMapAttr (scrbm, BMA_DEPTH);
  403.    fontX = topazfont->tf_XSize;
  404.    fontY = topazfont->tf_YSize;
  405.    minwidth = MINWIDTH;
  406.    coordsstringlen = 1;
  407.    if (scr->Width > 999)
  408.    {
  409.       coordsstringlen += 5;
  410.    }
  411.    else
  412.    {
  413.       coordsstringlen += 4;
  414.    }
  415.    if (scr->Height > 999)
  416.    {
  417.       coordsstringlen += 5;
  418.    }
  419.    else
  420.    {
  421.       coordsstringlen += 4;
  422.    }
  423.    if (coords || showrgb)
  424.    {
  425.       bottomoff = sizeih;
  426.       // center the text in the bottomborder
  427.       textoff = (bottomoff + fontY >> 1) - topazfont->tf_Baseline;
  428.       minwidth = 0;
  429.       if (coords)
  430.       {
  431.          minwidth = coordsstringlen * (fontX);
  432.       }
  433.       if (showrgb)
  434.       {
  435.          minwidth += 13 * (fontX);
  436.       }
  437.       // SysIHack or height of screenfont <= 8?
  438.       if ((bottomoff - 2) >= scr->Font->ta_YSize)
  439.       {
  440.          screenfont = OpenFont (scr->Font);
  441.          if (screenfont)
  442.          {
  443.             if (!(screenfont->tf_Flags & FPF_PROPORTIONAL))
  444.             {
  445.                fontX = screenfont->tf_XSize;
  446.                fontY = screenfont->tf_YSize;
  447.                minwidth = 0;
  448.                if (coords)
  449.                {
  450.                   minwidth = coordsstringlen * (fontX);
  451.                }
  452.                if (showrgb)
  453.                {
  454.                   minwidth += 13 * (fontX);
  455.                }
  456.                // center the text in the bottomborder
  457.                textoff = (bottomoff + fontY >> 1) - screenfont->tf_Baseline;
  458.             }
  459.             else
  460.             {
  461.                CloseFont (screenfont);
  462.                screenfont = NULL;               
  463.             }
  464.          }
  465.       }
  466.    }  // if (coords
  467.    else
  468.    {
  469.       bottomoff = scr->WBorBottom;
  470.    }
  471. }
  472.  
  473. void setwintitle ()
  474. {
  475.  LONG args[] = { (LONG) "Lupe", scalefac };
  476.  
  477.    RawDoFmt ("%s %ld:1", args, (void (*)()) Putchar, title);
  478.    SetWindowTitles (mywin, title, (STRPTR) ~0);
  479. }
  480.  
  481. void setmenu ()
  482. {
  483.  struct MenuItem *mitem;
  484.  
  485.    if (mywin)
  486.    {
  487.       ClearMenuStrip (mywin);
  488.  
  489.       mitem = ItemAddress (menu, FULLMENUNUM (0, 3, NOSUB));
  490.       if (scalefac > 1) mitem->Flags |= ITEMENABLED;
  491.       else mitem->Flags &= ~ITEMENABLED;
  492.  
  493.       mitem = ItemAddress (menu, FULLMENUNUM (0, 5, NOSUB));
  494.       if (enable) mitem->Flags |= CHECKED;
  495.       else mitem->Flags &= ~CHECKED;
  496.  
  497.       mitem = mitem->NextItem;
  498.       if (fixed) mitem->Flags |= CHECKED;
  499.       else mitem->Flags &= ~CHECKED;
  500.  
  501.       mitem = mitem->NextItem;
  502.       if (fast) mitem->Flags |= CHECKED;
  503.       else mitem->Flags &= ~CHECKED;
  504.  
  505.       mitem = mitem->NextItem;
  506.       if (coords) mitem->Flags |= CHECKED;
  507.       else mitem->Flags &= ~CHECKED;
  508.  
  509.       mitem = mitem->NextItem;
  510.       if (crosshair) mitem->Flags |= CHECKED;
  511.       else mitem->Flags &= ~CHECKED;
  512.  
  513.       mitem = mitem->NextItem;
  514.       if (grid) mitem->Flags |= CHECKED;
  515.       else mitem->Flags &= ~CHECKED;
  516.  
  517.       mitem = mitem->NextItem;
  518.       if (showrgb) mitem->Flags |= CHECKED;
  519.       else mitem->Flags &= ~CHECKED;
  520.  
  521.       mitem = ItemAddress (menu, FULLMENUNUM (0, 15, NOSUB));
  522.       if (hideonclose) mitem->Flags |= CHECKED;
  523.       else mitem->Flags &= ~CHECKED;
  524.  
  525.       ResetMenuStrip (mywin, menu);
  526.    }
  527. }
  528.  
  529. void setupgrid ()
  530. {
  531.    if (maskbm)
  532.    {
  533.       FreeBitMap (maskbm);
  534.       maskbm = NULL;
  535.    }
  536.    if (grid)
  537.    {
  538.       maskbm = AllocBitMap (innerwidth, innerheight, 1, BMF_CLEAR, destbm);
  539.       if (!maskbm)
  540.       {
  541.          error ("'AllocBitMap' for grid mask failed.");
  542.          grid = FALSE;
  543.          setmenu ();
  544.       }
  545.       else
  546.       {
  547.          LONG i, j;
  548.  
  549.          maskrp.BitMap = maskbm;
  550.          for (i = scalefac - 1; i < innerwidth; i += scalefac)
  551.          {
  552.             RectFill (&maskrp, i, 0, i, innerheight - 1)
  553.          }
  554.          for (i = scalefac - 1; i < innerheight; i += scalefac)
  555.          {
  556.             for (j = 0; j < innerwidth; j += scalefac)
  557.             {
  558.                RectFill (&maskrp, j, i, j + scalefac - 2, i);
  559.             }
  560.          }
  561.       }
  562.    }
  563. }
  564.  
  565. int allocbm ()
  566. {
  567.    if (destbm)
  568.    {
  569.       FreeBitMap (destbm);
  570.       destbm = NULL;
  571.    }
  572.    if (srcbm)
  573.    {
  574.       FreeBitMap (srcbm);
  575.       srcbm = NULL;
  576.    }
  577.    if (cyberdata)
  578.    {
  579.       FreeVec (cyberdata);
  580.       cyberdata = NULL;
  581.    }
  582.    winx = mywin->Width;
  583.    winy = mywin->Height;
  584.    innerwidth = winx - (leftoff + rightoff);
  585.    innerheight = winy - (topoff + bottomoff);
  586.    sourcewidth = innerwidth / scalefac;
  587.    sourceheight = innerheight / scalefac;
  588.    if (scalefac > 1)
  589.    {
  590.       if (cybergfxscreen)
  591.       {
  592.          if (!(cyberdata = AllocVec (sourcewidth * sourceheight * CYBERARRAY_BPP, MEMF_PUBLIC)))
  593.          {
  594.             error ("Can't allocate %ld Bytes for CyberPixelArray.", sourcewidth * sourceheight * CYBERARRAY_BPP);
  595.             return 1;
  596.          }
  597.          if (!(destbm = AllocBitMap (innerwidth, innerheight, 24, BMF_CLEAR | BMF_MINPLANES | PIXFMT_RGB24, 0)))
  598.          {
  599.             error ("'AllocBitMap' for destination bitmap failed.");
  600.             return 2;
  601.          }
  602.       }
  603.       else
  604.       {
  605.          if (!(srcbm = AllocBitMap (sourcewidth, sourceheight, scrdepth, BMF_CLEAR, scrbm)))
  606.          {
  607.             error ("'AllocBitMap' for source bitmap failed.");
  608.             return 3;
  609.          }
  610.          if (!(destbm = AllocBitMap (innerwidth, innerheight, scrdepth, BMF_CLEAR, srcbm)))
  611.          {
  612.             error ("'AllocBitMap' for destination bitmap failed.");
  613.             return 4;
  614.          }
  615.          bsa.bsa_SrcWidth = sourcewidth;
  616.          bsa.bsa_SrcHeight = sourceheight;
  617.          bsa.bsa_DestWidth = innerwidth;
  618.          bsa.bsa_DestHeight = innerheight;
  619.          bsa.bsa_SrcBitMap = srcbm;
  620.          bsa.bsa_DestBitMap = destbm;
  621.          bsa.bsa_XDestFactor = bsa.bsa_YDestFactor = scalefac;
  622.       }
  623.       setupgrid ();
  624.       destrp.BitMap = destbm;
  625.    }
  626.    return 0;
  627. }
  628.  
  629. BOOL makescreensmenu ()
  630. {
  631.  struct NewMenu tmpmenu[] = {
  632.   { NM_SUB, 0, 0, 0, 0, 0 },
  633.   { NM_END, 0, 0, 0, 0, 0 }
  634.  };
  635.  ULONG lock;
  636.  struct List *pubscreenlist;
  637.  struct PubScreenNode *pubscreennode;
  638.  struct MenuItem **itempointer = &menu->FirstItem->NextItem->SubItem;
  639.  
  640.    lock = LockIBase (0);
  641.    tmpscr = IntuitionBase->FirstScreen;
  642.    if (tmpscr->NextScreen)
  643.    {
  644.       while ((tmpscr = tmpscr->NextScreen) != 0)
  645.       {
  646.          tmpmenu[0].nm_Label = tmpscr->DefaultTitle;
  647.          pubscreenlist = LockPubScreenList ();
  648.          if (pubscreenlist)
  649.          {
  650.             pubscreennode = (struct PubScreenNode *) pubscreenlist->lh_Head;
  651.             while (pubscreennode)
  652.             {
  653.                if (pubscreennode->psn_Screen == tmpscr)
  654.                {
  655.                   tmpmenu[0].nm_Label = pubscreennode->psn_Node.ln_Name;
  656.                   break;
  657.                }
  658.                pubscreennode = (struct PubScreenNode *) pubscreennode->psn_Node.ln_Succ;
  659.             }
  660.             UnlockPubScreenList ();
  661.          }
  662.          tmpmenu[0].nm_UserData = tmpscr;
  663.          // each item single created
  664.          *itempointer = (struct MenuItem *) CreateMenusA (tmpmenu, NULL);
  665.          if (*itempointer)
  666.          {
  667.             itempointer = &(*itempointer)->NextItem;
  668.          }
  669.          else
  670.          {
  671.             error ("Can't create a screensmenu item.");
  672.          }
  673.       }
  674.    }
  675.    else
  676.    {
  677.       tmpmenu[0].nm_Label = "No Other Screen";
  678.       *itempointer = (struct MenuItem *) CreateMenusA (tmpmenu, NULL);
  679.       if (*itempointer)
  680.       {
  681.          (*itempointer)->Flags |= HIGHNONE;
  682.          itempointer = &(*itempointer)->NextItem;
  683.       }
  684.       else
  685.       {
  686.          error ("Can't create screensmenu.");
  687.       }
  688.    }
  689.    UnlockIBase (lock);
  690.    if (LayoutMenus (menu, VisualInfo, GTMN_NewLookMenus, TRUE, TAG_DONE))
  691.    {
  692.       return TRUE;
  693.    }
  694.    else
  695.    {
  696.       error ("Can't layout screensmenu.");
  697.    }
  698.    return FALSE;
  699. }
  700.  
  701. void freescreensmenu (struct MenuItem *menuitem)
  702. {
  703.    if (menuitem)
  704.    {
  705.       freescreensmenu (menuitem->NextItem);
  706.       FreeMenus ((struct Menu *) menuitem);
  707.    }
  708. }
  709.  
  710. BOOL openwin ()
  711. {
  712.  ULONG lock;
  713.  WORD bw, rh;
  714.  struct Rectangle zoom = {
  715.     minwidth + leftoff + rightoff,
  716.     MINHEIGHT + topoff + bottomoff + sizeih,
  717.     -1, -1
  718.  };
  719.  
  720.    if (!mywin)
  721.    {
  722.       if (hires)
  723.       {
  724.          bw = rh = 2;
  725.       }
  726.       else
  727.       {
  728.          bw = rh = 1;
  729.       }
  730.       // first bring the screen to front
  731.       //  -> screen order in menu correct
  732.       lock = LockIBase (0);
  733.       tmpscr = IntuitionBase->FirstScreen;
  734.       UnlockIBase (lock);
  735.       if (tmpscr != scr)
  736.       {
  737.          if (jumpdirect)
  738.          {
  739.             ScreenToFront (scr);
  740.          }
  741.          else
  742.          {
  743.             ScreenToBack (tmpscr);
  744.          }
  745.       }
  746.       menu = CreateMenusA (standartmenu, NULL);
  747.       if (menu)
  748.       {
  749.          if (makescreensmenu ())
  750.          {
  751.             propgadget = (Object *) NewObject (NULL, PROPGCLASS,
  752.              PGA_Freedom,     FREEVERT,
  753.              ICA_TARGET,      ICTARGET_IDCMP,
  754.              PGA_NewLook,     TRUE,
  755.              PGA_Borderless,  newlook,
  756.              PGA_Total,       maxscalefac,
  757.              PGA_Visible,     1,
  758.              PGA_Top,         scalefac - 1,
  759.              GA_RelRight,     bw - sizeiw + 3,
  760.              GA_Top,          topoff + rh,
  761.              GA_Width,        sizeiw - bw - bw - 4,
  762.              GA_RelHeight,    -topoff - sizeih - rh - rh,
  763.              GA_RightBorder,  TRUE,
  764.              TAG_DONE);
  765.             if (propgadget)
  766.             {
  767.                if (innerwidth < minwidth)
  768.                {
  769.                   innerwidth = minwidth;
  770.                }
  771.                mywin = OpenWindowTags (NULL,
  772.                 WA_Flags,          WFLG_ACTIVATE | WFLG_CLOSEGADGET | WFLG_DEPTHGADGET
  773.                                     | WFLG_DRAGBAR | WFLG_SIZEGADGET | WFLG_SIMPLE_REFRESH
  774.                                     | WFLG_NEWLOOKMENUS | WFLG_REPORTMOUSE | WFLG_SIZEBRIGHT
  775.                                     | ((coords || showrgb) ? WFLG_SIZEBBOTTOM : 0),
  776.                 WA_AutoAdjust,     1,
  777.                 WA_MaxHeight,      10000,
  778.                 WA_MaxWidth,       10000,
  779.                 WA_MinHeight,      MINHEIGHT + topoff + bottomoff,
  780.                 WA_MinWidth,       minwidth + leftoff + rightoff,
  781.                 WA_IDCMP,          IDCMP_CLOSEWINDOW | IDCMP_IDCMPUPDATE | IDCMP_NEWSIZE
  782.                                     | IDCMP_MENUPICK | IDCMP_ACTIVEWINDOW
  783.                                     | IDCMP_INACTIVEWINDOW | IDCMP_MOUSEBUTTONS
  784.                                     | IDCMP_MOUSEMOVE | IDCMP_VANILLAKEY | IDCMP_RAWKEY
  785.                                     | IDCMP_REFRESHWINDOW,
  786.                 WA_InnerHeight,    innerheight,
  787.                 WA_InnerWidth,     innerwidth,
  788.                 WA_Left,           winleft,
  789.                 WA_Gadgets,        propgadget,
  790.                 WA_Top,            wintop,
  791.                 WA_PubScreen,      scr,
  792.                 WA_Zoom,           &zoom,
  793.                 TAG_DONE);
  794.                if (mywin)
  795.                {
  796.                   // shit patches
  797.                   leftoff = mywin->BorderLeft;
  798.                   bottomoff = mywin->BorderBottom;
  799.                   SetMenuStrip (mywin, menu);
  800.                   setmenu ();
  801.                   setwintitle ();
  802.                   userport = mywin->UserPort;
  803.                   winrp = mywin->RPort;
  804.                   if (screenfont)
  805.                   {
  806.                      SetFont (winrp, screenfont);
  807.                   }
  808.                   else
  809.                   {
  810.                      SetFont (winrp, topazfont);
  811.                   }
  812.                   SetAPen (winrp, pens[0]);
  813.                   SetBPen (winrp, pens[1]);
  814.                   waitmask |= 1 << userport->mp_SigBit;
  815.                   return TRUE;
  816.                }
  817.                else
  818.                {
  819.                   error ("Can't open window.");
  820.                }
  821.             }
  822.             else
  823.             {
  824.                error ("Can't create propgadget.");
  825.             }
  826.          }
  827.       }
  828.       else
  829.       {
  830.          error ("Can't create menu.");
  831.       }
  832.       return FALSE;
  833.    }
  834.    return TRUE;  // win already open
  835. }
  836.  
  837. void closewin ()
  838. {
  839.    if (mywin)
  840.    {
  841.       if (menu)
  842.       {
  843.          ClearMenuStrip (mywin);
  844.       }
  845.       wintop = mywin->TopEdge;
  846.       winleft = mywin->LeftEdge;
  847.       waitmask &= ~(1 << userport->mp_SigBit);
  848.       CloseWindow (mywin);
  849.       mywin = NULL;
  850.       userport = NULL;
  851.    }
  852.    if (menu)
  853.    {
  854.       freescreensmenu (ItemAddress (menu, FULLMENUNUM (0, 1, 0)));
  855.       FreeMenus (menu);
  856.       menu = NULL;
  857.    }
  858.    if (propgadget)
  859.    {
  860.       DisposeObject (propgadget);
  861.       propgadget = NULL;
  862.    }
  863.    if (srcbm)
  864.    {
  865.       FreeBitMap (srcbm);
  866.       srcbm = NULL;
  867.    }
  868.    if (destbm)
  869.    {
  870.       FreeBitMap (destbm);
  871.       destbm = NULL;
  872.    }
  873.    if (maskbm)
  874.    {
  875.       FreeBitMap (maskbm);
  876.       maskbm = NULL;
  877.    }
  878.    if (cyberdata)
  879.    {
  880.       FreeVec (cyberdata);
  881.       cyberdata = NULL;
  882.    }
  883. }
  884.  
  885. BOOL screen_is_still_open ()
  886. {
  887.    tmpscr = IntuitionBase->FirstScreen;
  888.    while (tmpscr)
  889.    {
  890.       if (tmpscr == scr)
  891.       {
  892.          return TRUE;
  893.       }
  894.       tmpscr = tmpscr->NextScreen;
  895.    }
  896.    return FALSE;
  897. }
  898.  
  899. void freeappicon ()
  900. {
  901.    if (appicon)
  902.    {
  903.       RemoveAppIcon (appicon);
  904.       appicon = NULL;
  905.    }
  906.    if (app_mp)
  907.    {
  908.       waitmask &= ~(1 << app_mp->mp_SigBit);
  909.       DeleteMsgPort (app_mp);
  910.       app_mp = NULL;
  911.    }
  912.    if (icon)
  913.    {
  914.       FreeDiskObject (icon);
  915.       icon = NULL;
  916.    }
  917. }
  918.  
  919. BOOL showwindow ()
  920. {
  921.    if (!mywin)
  922.    {
  923.       if (!screen_is_still_open ()) scr = NULL;
  924.       {
  925.          if (setupscreen (scr))
  926.          {
  927.             return FALSE;
  928.          }
  929.          getoffsets ();
  930.          if (!openwin ())
  931.          {
  932.             return FALSE;
  933.          }
  934.          if (allocbm ())
  935.          {
  936.             return FALSE;
  937.          }
  938.       }
  939.       freeappicon ();
  940.    }
  941.    return TRUE;
  942. }
  943.  
  944. void hidewindow ()
  945. {
  946.    closewin ();
  947.    CloseDownScreen ();
  948.  
  949.    freeappicon ();
  950.  
  951.    if (Cli ())
  952.    {
  953.       GetProgramName (programname, 108);
  954.    }
  955.    else
  956.    {
  957.       strncpy (programname, thistask->tc_Node.ln_Name, 108);
  958.    }
  959.    if ((icon = GetDiskObject ("ENV:sys/def_Lupe")) == 0)
  960.    {
  961.       if ((icon = GetDiskObject (programname)) == 0)
  962.       {
  963.          icon = GetDefDiskObject (WBTOOL);
  964.       }
  965.    }
  966.    if (icon)
  967.    {
  968.       app_mp = CreateMsgPort ();
  969.       if (app_mp)
  970.       {
  971.          appicon = AddAppIcon (1, 0, "Lupe", app_mp, NULL, icon, NULL);
  972.          if (appicon)
  973.          {
  974.             waitmask |= 1 << app_mp->mp_SigBit;
  975.          }
  976.       }
  977.    }
  978. }
  979.  
  980. void printcoords (LONG x, LONG y)
  981. {
  982.  char dispstring[12];
  983.  LONG args[] = {x - originX, y - originY};
  984.  
  985.    if (coords)
  986.    {
  987.       memset (dispstring, ' ', coordsstringlen);
  988.       RawDoFmt ("%ld,%ld", args, (void (*)()) Putchar, dispstring);
  989.       dispstring[strlen (dispstring)] = ' ';
  990.       mywin->Flags &= ~SIZEGADGET;
  991.       if ((winx == mywin->Width) && (winy == mywin->Height))
  992.       {
  993.          Move (winrp, leftoff, mywin->Height - textoff);
  994.          Text (winrp, dispstring, coordsstringlen);
  995.       }
  996.       mywin->Flags |= SIZEGADGET;
  997.    }
  998. }
  999.  
  1000. void printrgb (LONG x, LONG y)
  1001. {
  1002.  ULONG colorreg, colors[3], apen, color, textlen;
  1003.  char dispstring[12];
  1004.  
  1005.    if (showrgb)
  1006.    {
  1007.       colorreg = ReadPixel (scrrp, x, y);
  1008.       if (cybergfxscreen)
  1009.       {
  1010.          color = ReadRGBPixel (scrrp, x, y);
  1011.          colors[0] = (color >> 16) & 0xff;
  1012.          colors[1] = (color >> 8) & 0xff;
  1013.          colors[2] = color & 0xff;
  1014.       }
  1015.       else
  1016.       {
  1017.          GetRGB32 (scr->ViewPort.ColorMap, colorreg, 1, colors);
  1018.          colors[0] &= 0xff;
  1019.          colors[1] &= 0xff;
  1020.          colors[2] &= 0xff;
  1021.       }
  1022.       RawDoFmt ("%3ld,%3ld,%3ld", colors, (void (*)()) Putchar, dispstring);
  1023.       textlen = TextLength (winrp, dispstring, 11);
  1024.       apen = GetAPen (winrp);
  1025.       mywin->Flags &= ~SIZEGADGET;
  1026.       if ((winx == mywin->Width) && (winy == mywin->Height))
  1027.       {        
  1028.          Move (winrp, innerwidth - textlen, mywin->Height - textoff);
  1029.          Text (winrp, dispstring, 11);
  1030.          SetAPen (winrp, pens[5]);
  1031.          Move (winrp, innerwidth - textlen - fontX - 1, mywin->Height - (bottomoff - fontY >> 1) - 2);
  1032.          Draw (winrp, innerwidth - textlen - fontX - 1, mywin->Height - (bottomoff - fontY >> 1) - fontY);
  1033.          Draw (winrp, innerwidth - textlen - 2, mywin->Height - (bottomoff - fontY >> 1) - fontY);
  1034.          SetAPen (winrp, pens[4]);
  1035.          Move (winrp, innerwidth - textlen - 1, mywin->Height - (bottomoff - fontY >> 1) - fontY + 1);
  1036.          Draw (winrp, innerwidth - textlen - 1, mywin->Height - (bottomoff - fontY >> 1) - 1);
  1037.          Draw (winrp, innerwidth - textlen - fontX, mywin->Height - (bottomoff - fontY >> 1) - 1);
  1038.          SetAPen (winrp, colorreg);
  1039.          RectFill (winrp, innerwidth - textlen - fontX, mywin->Height - (bottomoff - fontY >> 1) - fontY + 1,
  1040.             innerwidth - textlen - 2, mywin->Height - (bottomoff - fontY >> 1) - 2);
  1041.       }
  1042.       mywin->Flags |= SIZEGADGET;
  1043.       SetAPen (winrp, apen);
  1044.    }  // if (showrgb)
  1045. }
  1046.  
  1047. void refresh ()
  1048. {
  1049.  LONG x, y, xoff = 0, yoff = 0;
  1050.  
  1051.    if (mywin)
  1052.    {
  1053.       // set the coordinates
  1054.       if (enable)
  1055.       {
  1056.          if (fixed)
  1057.          {
  1058.             x = fixedX;
  1059.             y = fixedY;
  1060.          }
  1061.          else
  1062.          {
  1063.             x = scr->MouseX;
  1064.             y = scr->MouseY;
  1065.          }
  1066.          oldx = x;
  1067.          oldy = y;
  1068.       }
  1069.       else
  1070.       {
  1071.          x = oldx;
  1072.          y = oldy;
  1073.       }
  1074.       
  1075.       printcoords (x, y);
  1076.       printrgb (x, y);
  1077.  
  1078.       // adjust the coordinates
  1079.       x -= sourcewidth >> 1;
  1080.       y -= sourceheight >> 1;
  1081.       if (x < 0)
  1082.       {
  1083.          xoff = x;
  1084.          x = 0;
  1085.       }
  1086.       else if (x > (scr->Width - sourcewidth))
  1087.       {
  1088.          xoff = -(scr->Width - sourcewidth - x);
  1089.          x = scr->Width - sourcewidth;
  1090.       }
  1091.       if (y < 0)
  1092.       {
  1093.          yoff = y;
  1094.          y = 0;
  1095.       }
  1096.       else if (y > (scr->Height - sourceheight))
  1097.       {
  1098.          yoff = -(scr->Height - sourceheight - y);
  1099.          y = scr->Height - sourceheight;
  1100.       }
  1101.  
  1102.       // calculate the crosshair
  1103.       if (crosshair)
  1104.       {
  1105.          xoff = scalefac * ((sourcewidth >> 1) + xoff) + (scalefac >> 1);
  1106.          yoff = scalefac * ((sourceheight >> 1) + yoff) + (scalefac >> 1);
  1107.       }
  1108.  
  1109.       if (scalefac > 1)
  1110.       {
  1111.          // blit and scale
  1112.          if (cybergfxscreen)
  1113.          {
  1114.             // BitMapScale don't work with bitmaps >8 Bit (CyberGfx 2.15)
  1115.             ReadPixelArray (cyberdata, 0, 0, sourcewidth * CYBERARRAY_BPP, scrrp, x, y, sourcewidth, sourceheight, RECTFMT_RGB);
  1116.             ScalePixelArray (cyberdata, sourcewidth, sourceheight, sourcewidth * CYBERARRAY_BPP, &destrp, 0, 0, sourcewidth * scalefac, sourceheight * scalefac, RECTFMT_RGB);
  1117.          }
  1118.          else
  1119.          {
  1120.             BltBitMap (scrbm, x, y, srcbm, 0, 0, sourcewidth, sourceheight, ABNC | ABC, ~0, NULL);
  1121.             BitMapScale (&bsa);
  1122.          }
  1123.          // draw the grid
  1124.          if (grid)
  1125.          {
  1126.             SetDrMd (&destrp, JAM1);
  1127.             BltTemplate (maskbm->Planes[0], 0, maskbm->BytesPerRow, &destrp, 0, 0, sourcewidth * scalefac, sourceheight * scalefac);
  1128.          }
  1129.          // draw the crosshair
  1130.          if (crosshair)
  1131.          {
  1132.             SetDrMd (&destrp, COMPLEMENT);
  1133.             Move (&destrp, xoff, 0);
  1134.             Draw (&destrp, xoff, sourceheight * scalefac - 1);
  1135.             Move (&destrp, 0, yoff);
  1136.             Draw (&destrp, sourcewidth * scalefac - 1, yoff);
  1137.          }
  1138.          mywin->Flags &= ~SIZEGADGET;
  1139.          if ((winx == mywin->Width) && (winy == mywin->Height))
  1140.          {
  1141.             BltBitMapRastPort (destbm, 0, 0, winrp, leftoff, topoff, innerwidth, innerheight, ABNC | ABC);
  1142.          }
  1143.          mywin->Flags |= SIZEGADGET;
  1144.       }
  1145.       else  // 1:1 - mode
  1146.       {
  1147.          mywin->Flags &= ~SIZEGADGET;
  1148.          if ((winx == mywin->Width) && (winy == mywin->Height))
  1149.          {
  1150.             BltBitMapRastPort (scrbm, x, y, winrp, leftoff, topoff, innerwidth, innerheight, ABNC | ABC);
  1151.             // draw the crosshair in 1:1 - mode
  1152.             if (crosshair)
  1153.             {
  1154.                SetDrMd (winrp, COMPLEMENT);
  1155.                Move (winrp, leftoff + xoff, topoff);
  1156.                Draw (winrp, leftoff + xoff, topoff + innerheight - 1);
  1157.                Move (winrp, leftoff, topoff + yoff);
  1158.                Draw (winrp, leftoff + innerwidth - 1, topoff + yoff);
  1159.                SetDrMd (winrp, JAM2);
  1160.             }
  1161.          }
  1162.          mywin->Flags |= SIZEGADGET;
  1163.       }
  1164.    }
  1165. }
  1166.  
  1167. void CxFunction (CxMsg *cxm, CxObj *co)
  1168. {
  1169.  struct InputEvent *ie = (struct InputEvent *) CxMsgData (cxm);
  1170.  
  1171.    if (origin)
  1172.    {
  1173.       if (MatchIX (ie, &setoriginix))
  1174.       {
  1175.          originX = scr->MouseX;
  1176.          originY = scr->MouseY;
  1177.          DisposeCxMsg (cxm);
  1178.          return;
  1179.       }
  1180.       if (MatchIX (ie, &resetoriginix))
  1181.       {
  1182.          originX = originY = 0;
  1183.          DisposeCxMsg (cxm);
  1184.          return;
  1185.       }
  1186.    }
  1187.    if (showhide)
  1188.    {
  1189.       if (MatchIX (ie, &showhideix))
  1190.       {
  1191.          Signal (thistask, 1 << showhidesig);
  1192.       }
  1193.    }
  1194.    if ((ie->ie_Class == IECLASS_TIMER) || fast)
  1195.    {
  1196.       Signal (thistask, 1 << timesig);
  1197.    }
  1198. }
  1199.  
  1200. BOOL initbroker ()
  1201. {
  1202.  LONG errorcode;
  1203.  
  1204.    broker_mp = CreateMsgPort ();
  1205.    if (broker_mp)
  1206.    {
  1207.       newbroker.nb_Port = broker_mp;
  1208.       cxsigflag = 1 << broker_mp->mp_SigBit;
  1209.       broker = CxBroker (&newbroker, &errorcode);
  1210.       if (broker)
  1211.       {
  1212.          customcxobj = CxCustom (CxFunction, 0);
  1213.          if (customcxobj)
  1214.          {
  1215.             if (!CxObjError (customcxobj))
  1216.             {
  1217.                AttachCxObj (broker, customcxobj);
  1218.                if (ParseIX (setoriginkey, &setoriginix) || ParseIX (resetoriginkey, &resetoriginix))
  1219.                {
  1220.                   origin = FALSE;
  1221.                   error ("Can't init a Hotkey.\n%s disabled.", "'Set Origin'");
  1222.                }
  1223.                if (ParseIX (showhidekey, &showhideix))
  1224.                {
  1225.                   showhide = FALSE;
  1226.                   error ("Can't init a Hotkey.\n%s disabled.", "'Show/Hide Window'");
  1227.                }
  1228.                ActivateCxObj (broker, 1);
  1229.                return TRUE;
  1230.             }
  1231.             DeleteCxObj (customcxobj);
  1232.          }
  1233.          else
  1234.          {
  1235.             error ("Can't create commodity-custom-objekt.");
  1236.          }
  1237.          DeleteCxObjAll (broker);
  1238.       }
  1239.       else if (errorcode == CBERR_SYSERR)
  1240.       {
  1241.          error ("Can't create commodity-broker-objekt.");
  1242.       }
  1243.       DeleteMsgPort (broker_mp);
  1244.    }
  1245.    else
  1246.    {
  1247.       error ("Can't create messageport for commodity-broker");
  1248.    }
  1249.    return FALSE;
  1250. }
  1251.  
  1252. BOOL reopenwin ()
  1253. {
  1254.    closewin ();
  1255.    jump = TRUE;
  1256.    getoffsets ();
  1257.    if (!openwin ())
  1258.    {
  1259.       return FALSE;
  1260.    }
  1261.    if (allocbm ())
  1262.    {
  1263.       return FALSE;
  1264.    }
  1265.    return TRUE;
  1266. }
  1267.  
  1268. BOOL setpropgad ()
  1269. {
  1270.    if (allocbm ())
  1271.    {
  1272.       return FALSE;
  1273.    }
  1274.    SetAttrs (propgadget, PGA_Top, scalefac - 1);
  1275.    RefreshGList ((struct Gadget *) propgadget, mywin, NULL, 1);
  1276.    setwintitle ();
  1277.    return TRUE;
  1278. }
  1279.  
  1280. BOOL menupick (UWORD code)
  1281. {
  1282.  BOOL returnvalue = TRUE;
  1283.  static BOOL (*func)();
  1284.  
  1285.    while ((code != MENUNULL) && returnvalue && !jump)
  1286.    {
  1287.       item = ItemAddress (menu, code);
  1288.       if (SUBNUM (code) != NOSUB)
  1289.       {
  1290.          if (GTMENUITEM_USERDATA (item))  // 'no other screen'-submenu == 0
  1291.          {
  1292.             if (setupscreen ((struct Screen *) GTMENUITEM_USERDATA (item)))
  1293.             {
  1294.                return FALSE;
  1295.             }
  1296.             closewin ();
  1297.             jump = TRUE;
  1298.             getoffsets ();
  1299.             if (!openwin ())
  1300.             {
  1301.                return FALSE;
  1302.             }
  1303.             if (allocbm ())
  1304.             {
  1305.                return FALSE;
  1306.             }
  1307.          }
  1308.       }
  1309.       else
  1310.       {
  1311.          func = (BOOL (*)()) GTMENUITEM_USERDATA (item);
  1312.          returnvalue = func ();
  1313.       }
  1314.       if (!jump) code = item->NextSelect;
  1315.    }
  1316.    return returnvalue;
  1317. }
  1318.  
  1319. BOOL vanillakey (UWORD code)
  1320. {
  1321.  BOOL returnvalue = TRUE;
  1322.  
  1323.    switch (code)
  1324.    {
  1325.     case 'J':
  1326.     case 'j':
  1327.       returnvalue = jumpFunc ();
  1328.       break;
  1329.     case 'S':
  1330.     case 's':
  1331.       returnvalue = saveFunc ();
  1332.       break;
  1333.     case 'E':
  1334.     case 'e':
  1335.       enable = !enable;
  1336.       ActivateCxObj (broker, enable);
  1337.       setmenu ();
  1338.       break;
  1339.     case 'F':
  1340.     case 'f':
  1341.       fast = !fast;
  1342.       setmenu ();
  1343.       break;
  1344.     case 'C':
  1345.     case 'c':
  1346.       coords = !coords;
  1347.       returnvalue = reopenwin ();
  1348.       break;
  1349.     case 'R':
  1350.     case 'r':
  1351.       crosshair = !crosshair;
  1352.       setmenu ();
  1353.       break;
  1354.     case 'O':
  1355.     case 'o':
  1356.       originX = scr->MouseX;
  1357.       originY = scr->MouseY;
  1358.       break;
  1359.     case 'K':
  1360.     case 'k':
  1361.       originX = originY = 0;
  1362.       break;
  1363.     case 'D':
  1364.     case 'd':
  1365.       fixed = !fixed;
  1366.       fixedX = scr->MouseX;
  1367.       fixedY = scr->MouseY;
  1368.       setmenu ();
  1369.       break;
  1370.     case '?':
  1371.     case 'A':
  1372.     case 'a':
  1373.       returnvalue = AboutFunc ();
  1374.       break;
  1375.     case 'N':
  1376.     case 'n':
  1377.       hideonclose = !hideonclose;
  1378.       setmenu ();
  1379.       break;
  1380.     case 'I':
  1381.     case 'i':
  1382.       returnvalue = hideFunc ();
  1383.       break;
  1384.     case 'G':
  1385.     case 'g':
  1386.       grid = !grid;
  1387.       setupgrid ();
  1388.       setmenu ();
  1389.       break;
  1390.     case 'W':
  1391.     case 'w':
  1392.       showrgb = !showrgb;
  1393.       returnvalue = reopenwin ();
  1394.       break;
  1395.     case 'Q':
  1396.     case 'q':
  1397.       returnvalue = FALSE;
  1398.       break;
  1399.     case 27:  // ESC
  1400.       if (hideonclose)
  1401.       {
  1402.          hidewindow ();
  1403.          jump = TRUE;
  1404.       }
  1405.       else
  1406.       {
  1407.          returnvalue = FALSE;
  1408.       }
  1409.       break;
  1410.     case '+':
  1411.       if (scalefac < maxscalefac)
  1412.       {
  1413.          scalefac++;
  1414.          returnvalue = setpropgad ();
  1415.       }
  1416.       break;
  1417.     case '-':
  1418.       if (scalefac > 1)
  1419.       {
  1420.          scalefac--;
  1421.          returnvalue = setpropgad ();
  1422.       }
  1423.       break;
  1424.    }
  1425.    return returnvalue;
  1426. }
  1427.  
  1428. void rawkey (UWORD code, UWORD qualifier)
  1429. {
  1430.  BOOL returnvalue = TRUE;
  1431.  
  1432.    switch (code)
  1433.    {
  1434.     // up
  1435.     case 76:
  1436.       if (qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
  1437.       {
  1438.          fixedY -= sourceheight - 1;
  1439.          if (fixedY < 0) fixedY = 0;
  1440.       }
  1441.       else if (qualifier & (IEQUALIFIER_LALT | IEQUALIFIER_RALT))
  1442.       {
  1443.          fixedY = 0;
  1444.       }
  1445.       else if (fixedY) fixedY--;
  1446.       break;
  1447.     // down
  1448.     case 77:
  1449.       if (qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
  1450.       {
  1451.          fixedY += sourceheight - 1;
  1452.          if (fixedY > (scr->Height - 1)) fixedY = scr->Height - 1;
  1453.       }
  1454.       else if (qualifier & (IEQUALIFIER_LALT | IEQUALIFIER_RALT))
  1455.       {
  1456.          fixedY = scr->Height - 1;
  1457.       }
  1458.          else if (fixedY < (scr->Height - 1)) fixedY++;
  1459.          break;
  1460.     // right
  1461.     case 78:
  1462.       if (qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
  1463.       {
  1464.          fixedX += sourcewidth - 1;
  1465.          if (fixedX > (scr->Width - 1)) fixedX = scr->Width - 1;
  1466.       }
  1467.       else if (qualifier & (IEQUALIFIER_LALT | IEQUALIFIER_RALT))
  1468.       {
  1469.          fixedX = scr->Width - 1;
  1470.       }
  1471.       else if (fixedX < (scr->Width - 1)) fixedX++;
  1472.       break;
  1473.     // left
  1474.     case 79:
  1475.       if (qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
  1476.       {
  1477.          fixedX -= sourcewidth - 1;
  1478.          if (fixedX < 0) fixedX = 0;
  1479.       }
  1480.       else if (qualifier & (IEQUALIFIER_LALT | IEQUALIFIER_RALT))
  1481.       {
  1482.          fixedX = 0;
  1483.       }
  1484.       else if (fixedX) fixedX--;
  1485.       break;
  1486.    }
  1487. }
  1488.  
  1489. void processmsg ()
  1490. {
  1491.  struct IntuiMessage *intuimsg = NULL, m;
  1492.  CxMsg *msg;
  1493.  BOOL cont = TRUE, fixedmove = FALSE, app_clicked = FALSE;
  1494.  LONG sigmask, msgid, msgtype;;
  1495.  ULONG lock;
  1496.  
  1497.    waitmask |= (1 << timesig) | (1 << showhidesig) | cxsigflag | SIGBREAKF_CTRL_C;
  1498.    while (cont)
  1499.    {
  1500.       sigmask = Wait (waitmask);
  1501.       if (sigmask & cxsigflag)
  1502.       {
  1503.          while ((msg = (CxMsg *) GetMsg (broker_mp)) != 0)
  1504.          {
  1505.             msgid = CxMsgID (msg);
  1506.             msgtype = CxMsgType (msg);
  1507.             ReplyMsg ((struct Message *) msg);
  1508.             switch (msgtype)
  1509.             {
  1510.              case CXM_COMMAND:
  1511.                switch (msgid)
  1512.                {
  1513.                 case CXCMD_APPEAR:
  1514.                   cont = showwindow ();
  1515.                   break;
  1516.                 case CXCMD_DISAPPEAR:
  1517.                   hidewindow ();
  1518.                   break;
  1519.                 case CXCMD_DISABLE:
  1520.                   ActivateCxObj (broker, 0);
  1521.                   enable = FALSE;
  1522.                   setmenu ();
  1523.                   break;
  1524.                 case CXCMD_ENABLE:
  1525.                   ActivateCxObj (broker, 1);
  1526.                   enable = TRUE;
  1527.                   setmenu ();
  1528.                   break;
  1529.                 case CXCMD_UNIQUE:
  1530.                   cont = showwindow ();
  1531.                   break;
  1532.                 case CXCMD_KILL:
  1533.                   cont = FALSE;
  1534.                   break;
  1535.                }
  1536.             }
  1537.          }  // while ((msg
  1538.       }
  1539.       if (userport)
  1540.       {
  1541.          if (sigmask & (1 << userport->mp_SigBit))
  1542.          {
  1543.             jump = FALSE;
  1544.             while ((intuimsg = (struct IntuiMessage *) GetMsg (userport)) != 0)
  1545.             {
  1546.                CopyMem ((char *) intuimsg, (char *) &m, (long) sizeof (struct IntuiMessage));
  1547.                ReplyMsg ((struct Message *) intuimsg);
  1548.                switch (m.Class)
  1549.                {
  1550.                 case IDCMP_CLOSEWINDOW:
  1551.                   if (hideonclose)
  1552.                   {
  1553.                      hidewindow ();
  1554.                   }
  1555.                   else
  1556.                   {
  1557.                      cont = FALSE;
  1558.                   }
  1559.                   jump = TRUE;
  1560.                   break;
  1561.                 case IDCMP_NEWSIZE:
  1562.                   if (allocbm ())
  1563.                   {
  1564.                      cont = FALSE;
  1565.                   }
  1566.                   break;
  1567.                 case IDCMP_IDCMPUPDATE:
  1568.                   ULONG h;
  1569.                   GetAttr (PGA_Top, propgadget, &h);
  1570.                   if (++h != scalefac)
  1571.                   {
  1572.                      scalefac = h;
  1573.                      if (allocbm ()) cont = FALSE;
  1574.                      setwintitle ();
  1575.                      setmenu ();
  1576.                   }
  1577.                   break;
  1578.                 case IDCMP_MENUPICK:
  1579.                   cont = menupick (m.Code);
  1580.                   break;
  1581.                 case IDCMP_ACTIVEWINDOW:
  1582.                   SetAPen (winrp, pens[0]);
  1583.                   SetBPen (winrp, pens[1]);
  1584.                   printcoords (oldx, oldy);
  1585.                   printrgb (oldx, oldy);
  1586.                   ClearMenuStrip (mywin);
  1587.                   freescreensmenu (ItemAddress (menu, FULLMENUNUM (0, 1, 0)));
  1588.                   if (makescreensmenu ())
  1589.                   {
  1590.                      SetMenuStrip (mywin, menu);
  1591.                   }
  1592.                   else
  1593.                   {
  1594.                      cont = FALSE;
  1595.                   }
  1596.                   break;
  1597.                 case IDCMP_INACTIVEWINDOW:
  1598.                   SetAPen (winrp, pens[2]);
  1599.                   SetBPen (winrp, pens[3]);
  1600.                   printcoords (oldx, oldy);
  1601.                   printrgb (oldx, oldy);
  1602.                   break;
  1603.                 case IDCMP_MOUSEBUTTONS:
  1604.                   if (fixed)
  1605.                   {
  1606.                      if (m.Code == SELECTDOWN)
  1607.                      {
  1608.                         fixedmove = TRUE;
  1609.                      }
  1610.                      else
  1611.                      {
  1612.                         fixedmove = FALSE;
  1613.                      }
  1614.                   }
  1615.                   break;
  1616.                 case IDCMP_MOUSEMOVE:
  1617.                   if (fixedmove)
  1618.                   {
  1619.                      fixedX = scr->MouseX;
  1620.                      fixedY = scr->MouseY;
  1621.                   }
  1622.                   break;
  1623.                 case IDCMP_VANILLAKEY:
  1624.                   cont = vanillakey (m.Code);
  1625.                   break;
  1626.                 case IDCMP_RAWKEY:
  1627.                   rawkey (m.Code, m.Qualifier);
  1628.                   break;
  1629.                 case IDCMP_REFRESHWINDOW:
  1630.                   refresh ();
  1631.                   break;
  1632.                }
  1633.                if (jump)
  1634.                {
  1635.                   break;
  1636.                }
  1637.             }  // while (intuimsg
  1638.          }
  1639.       }  // if (userport)
  1640.       if (app_mp)
  1641.       {
  1642.          if (sigmask & (1 << app_mp->mp_SigBit))
  1643.          {
  1644.             app_clicked = FALSE;
  1645.             while ((appmsg = (struct AppMessage *) GetMsg (app_mp)) != 0)
  1646.             {
  1647.                ReplyMsg ((struct Message *) appmsg);
  1648.                app_clicked = TRUE;
  1649.             }
  1650.             if (app_clicked)
  1651.             {
  1652.                showwindow ();
  1653.             }
  1654.          }
  1655.       }
  1656.       if ((sigmask & (1 << showhidesig)) && cont)
  1657.       {
  1658.          if (mywin)
  1659.          {
  1660.             hidewindow ();
  1661.          }
  1662.          else
  1663.          {
  1664.             showwindow ();
  1665.          }
  1666.       }
  1667.       if ((sigmask & (1 << timesig)) && cont)
  1668.       {
  1669.          if (mywin)
  1670.          {
  1671.             // refresh only if we living on the active screen
  1672.             lock = LockIBase (0);
  1673.             tmpscr = IntuitionBase->ActiveScreen;
  1674.             UnlockIBase (lock);
  1675.             if (scr == tmpscr)
  1676.             {
  1677.                refresh ();
  1678.             }
  1679.          }
  1680.       }
  1681.       if (sigmask & SIGBREAKF_CTRL_C)
  1682.       {
  1683.          cont = FALSE;
  1684.       }
  1685.    }  // while (cont)
  1686. }
  1687.  
  1688. BOOL fixedFunc ()
  1689. {
  1690.    if (!fixed && (item->Flags & CHECKED))
  1691.    {
  1692.       fixed = TRUE;
  1693.       fixedX = scr->MouseX;
  1694.       fixedY = scr->MouseY;
  1695.    }
  1696.    else if (fixed && !(item->Flags & CHECKED))
  1697.    {
  1698.       fixed = FALSE;
  1699.    }
  1700.    return TRUE;
  1701. }
  1702.  
  1703. BOOL fastFunc ()
  1704. {
  1705.    fast = (item->Flags & CHECKED) != 0;
  1706.    return TRUE;
  1707. }
  1708.  
  1709. BOOL crosshairFunc ()
  1710. {
  1711.    crosshair = (item->Flags & CHECKED) != 0;
  1712.    return TRUE;
  1713. }
  1714.  
  1715. BOOL AboutFunc ()
  1716. {
  1717.    EasyRequestArgs (NULL, &es_about, NULL, era_about);
  1718.    return TRUE;
  1719. }
  1720.  
  1721. BOOL jumpFunc ()
  1722. {
  1723.  int returnvalue;
  1724.  
  1725.    if (!(returnvalue = setupscreen (NULL)))
  1726.    {
  1727.       return reopenwin ();
  1728.    }
  1729.    else if (returnvalue == 1)
  1730.    {
  1731.       return TRUE;  // no other screen
  1732.    }
  1733.    return FALSE;
  1734. }
  1735.  
  1736. BOOL openfilereq ()
  1737. {
  1738.  APTR request;
  1739.  
  1740.    request = AllocAslRequestTags (ASL_FileRequest,
  1741.     ASLFR_InitialHeight, scr->Height / 2,
  1742.     ASLFR_Screen, scr,
  1743.     ASLFR_SleepWindow, TRUE,
  1744.     ASLFR_Window, mywin,
  1745.     ASLFR_TitleText, "Save IFF",
  1746.     ASLFR_InitialDrawer, iffpath,
  1747.     ASLFR_InitialFile, iffname,
  1748.     ASLFR_DoSaveMode, TRUE,
  1749.     ASLFR_RejectIcons, TRUE, TAG_DONE);
  1750.    if (request)
  1751.    {
  1752.       if (AslRequest (request, NULL))
  1753.       {
  1754.          strncpy (iffpath, ((struct FileRequester *) request)->fr_Drawer, 255);
  1755.          strncpy (iffname, ((struct FileRequester *) request)->fr_File, 108);
  1756.          FreeAslRequest (request);
  1757.          return TRUE;
  1758.       }
  1759.    }
  1760.    return FALSE;
  1761. }
  1762.  
  1763. void write (register __d4 APTR buffer, register __d5 LONG size)
  1764. {
  1765.    if (Write (fh, buffer, size) != size)
  1766.    {
  1767.       throw (1);
  1768.    }
  1769. }
  1770.  
  1771. ULONG compressline (register __a3 UBYTE *src, register __a4 UBYTE *dest, ULONG size)
  1772. {
  1773.  register UBYTE x, y, *tmp, *deststart;
  1774.    
  1775.    deststart = dest;
  1776.    while (size > 1)
  1777.    {
  1778.       if (*src == src[1])
  1779.       {
  1780.          y = *src++;
  1781.          x = 0;
  1782.          size--;
  1783.          while (size && (x < 127) && (*src == y))
  1784.          {
  1785.             size--;
  1786.             x++;
  1787.             src++;
  1788.          }
  1789.          *dest++ = -x;
  1790.          *dest++ = y;
  1791.       }
  1792.       else
  1793.       {
  1794.          tmp = dest++;
  1795.          y = *src++;
  1796.          x = 0;
  1797.          while (size && (x < 128) && (*src != y))
  1798.          {
  1799.             size--;
  1800.             x++;
  1801.             *dest++ = y;
  1802.             y = *src++;
  1803.          }
  1804.          *tmp = x - 1;
  1805.          src--;
  1806.       }
  1807.    }
  1808.    if (size)
  1809.    {
  1810.       *dest++ = 0;
  1811.       *dest++ = *src;
  1812.    }
  1813.    return dest - deststart;
  1814. }
  1815.  
  1816. void saveiff ()
  1817. {
  1818.  ULONG len, bodylen, packlen, vpmodeid, colors[3];;
  1819.  UWORD i, j, byteoff, depth, bpr = ((innerwidth >> 3) + 2) & 0xfffe;
  1820.  register UWORD x, y;
  1821.  UBYTE cmap[3], *mem, *mem2, r, g, b, *offset;
  1822.  struct BitMapHeader bh;
  1823.  struct DisplayInfo di;
  1824.  char header[] = "FORM....ILBMANNO";
  1825.  char anno[] = "Written by " VERSION "\0";
  1826.  
  1827.    try
  1828.    {
  1829.       // save header
  1830.       depth = GetBitMapAttr (destbm, BMA_DEPTH);
  1831.       write (header, strlen (header));
  1832.       len = (strlen (anno) + 2) & 0xfe;
  1833.       write (&len, 4);
  1834.       write (anno, len);
  1835.       write ("BMHD", 4);
  1836.       len = sizeof (struct BitMapHeader);
  1837.       write (&len, 4);
  1838.       bh.bmh_Width = innerwidth;
  1839.       bh.bmh_Height = innerheight;
  1840.       bh.bmh_Left = bh.bmh_Top = 0;
  1841.       bh.bmh_Depth = depth;
  1842.       bh.bmh_Masking = 0;
  1843.       bh.bmh_Compression = 1;
  1844.       bh.bmh_Pad = 0;
  1845.       bh.bmh_Transparent = 0;
  1846.       vpmodeid = GetVPModeID (&scr->ViewPort);
  1847.       if (GetDisplayInfoData (NULL, (UBYTE *) &di, sizeof (struct DisplayInfo), DTAG_DISP, vpmodeid))
  1848.       {
  1849.          bh.bmh_XAspect = di.Resolution.x;
  1850.          bh.bmh_YAspect = di.Resolution.y;
  1851.       }
  1852.       else
  1853.       {
  1854.          bh.bmh_XAspect = bh.bmh_YAspect = 0;
  1855.       }
  1856.       bh.bmh_PageWidth = innerwidth;
  1857.       bh.bmh_PageHeight = innerheight;
  1858.       write (&bh, len);
  1859.       write ("CAMG", 4);
  1860.       len = 4;
  1861.       write (&len, 4);
  1862.       write (&vpmodeid, 4);
  1863.       if (!cybergfxscreen)
  1864.       {
  1865.          write ("CMAP", 4);
  1866.          len = 3 * (1 << depth);
  1867.          write (&len, 4);
  1868.          for (i = 0; i < (1 << depth); i++)
  1869.          {
  1870.             GetRGB32 (scr->ViewPort.ColorMap, i, 1, colors);
  1871.             cmap[0] = colors[0] & 0xff;
  1872.             cmap[1] = colors[1] & 0xff;
  1873.             cmap[2] = colors[2] & 0xff;
  1874.             write (cmap, 3);
  1875.          }
  1876.       }
  1877.       write ("BODY....", 8);
  1878.       bodylen = Seek (fh, 0, OFFSET_CURRENT) - 4;
  1879.       
  1880.       if (cybergfxscreen)
  1881.       {
  1882.          // 24 Bit
  1883.          mem = (UBYTE *) AllocVec (bpr * 24, 0);
  1884.          mem2 = (UBYTE *) AllocVec (bpr << 1, 0);
  1885.          if (mem && mem2)
  1886.          {
  1887.             len = 0;
  1888.             for (i = 0; i < destbm->Rows; i++)
  1889.             {
  1890.                memset (mem, 0, bpr * 24);
  1891.                offset = destbm->Planes[0] + i * bpr * 24;
  1892.                for (j = 0, y = 7; j < (bpr * 24); j++, y--)
  1893.                {
  1894.                   r = *(offset + j++);
  1895.                   g = *(offset + j++);
  1896.                   b = *(offset + j);
  1897.                   if (y > 7) y = 7;
  1898.                   byteoff = j / 24;
  1899.                   for (x = 0; x < 8; x++)
  1900.                   {
  1901.                      mem[x*bpr+byteoff] |= ((r >> x) & 1u) << y;
  1902.                      mem[(x+8)*bpr+byteoff] |= ((g >> x) & 1u) << y;
  1903.                      mem[(x+16)*bpr+byteoff] |= ((b >> x) & 1u) << y;
  1904.                   }
  1905.                }
  1906.                for (j = 0; j < (bpr * 24); j += bpr)
  1907.                {
  1908.                   packlen = compressline (&mem[j], mem2, bpr);
  1909.                   write (mem2, packlen);
  1910.                }
  1911.                Move (winrp, leftoff, i + topoff);
  1912.                Draw (winrp, innerwidth + leftoff - 1, i + topoff);
  1913.             }
  1914.             FreeVec (mem);
  1915.             FreeVec (mem2);
  1916.          }
  1917.          else
  1918.          {
  1919.             throw (2);
  1920.          }  // if (mem)
  1921.       }
  1922.       else
  1923.       {
  1924.          mem = (UBYTE *) AllocVec (destbm->BytesPerRow << 1, 0);
  1925.          if (mem)
  1926.          {
  1927.             if (GetBitMapAttr (destbm, BMA_FLAGS) & BMF_INTERLEAVED)
  1928.             {
  1929.                // interleaved
  1930.                for (i = 0, len = 0; i < (destbm->Rows * depth); i++, len += destbm->BytesPerRow / depth)
  1931.                {
  1932.                   packlen = compressline (destbm->Planes[0] + len, mem, destbm->BytesPerRow / depth);
  1933.                   write (mem, packlen);
  1934.                   if (!(i % depth))
  1935.                   {
  1936.                      Move (winrp, leftoff, i / depth + topoff);
  1937.                      Draw (winrp, innerwidth + leftoff - 1, i / depth + topoff);
  1938.                   }
  1939.                }
  1940.             }
  1941.             else
  1942.             {
  1943.                len = 0;
  1944.                for (i = 0; i < destbm->Rows; i++)
  1945.                {
  1946.                   for (j = 0; j < depth; j++)
  1947.                   {
  1948.                      packlen = compressline (destbm->Planes[j] + len, mem, destbm->BytesPerRow);
  1949.                      write (mem, packlen);
  1950.                   }
  1951.                   len += destbm->BytesPerRow;
  1952.                   Move (winrp, leftoff, i + topoff);
  1953.                   Draw (winrp, innerwidth + leftoff - 1, i + topoff);
  1954.                }
  1955.             }
  1956.             FreeVec (mem);
  1957.          }
  1958.          else
  1959.          {
  1960.             throw (3);
  1961.          }
  1962.       }  // if (cybergfxscreen)
  1963.       if (Seek (fh, 0, OFFSET_CURRENT) & 1)
  1964.       {
  1965.          r = 0x80;
  1966.          write (&r, 1);
  1967.       }
  1968.       len = Seek (fh, 4, OFFSET_BEGINNING) - 8;
  1969.       write (&len, 4);
  1970.       Seek (fh, bodylen, OFFSET_BEGINNING);
  1971.       len = len - bodylen + 4;
  1972.       write (&len, 4);
  1973.    }
  1974.    catch (int) { }
  1975. }
  1976.  
  1977. BOOL saveFunc ()
  1978. {
  1979.  BPTR dirlock, olddirlock;
  1980.  ULONG reg;
  1981.  
  1982.    if (openfilereq ())
  1983.    {
  1984.       BltBitMapRastPort (destbm, 0, 0, winrp, leftoff, topoff, innerwidth, innerheight, ABNC | ABC);
  1985.       dirlock = Lock (iffpath, SHARED_LOCK);
  1986.       if (dirlock)
  1987.       {
  1988.          olddirlock = CurrentDir (dirlock);
  1989.          fh = Open (iffname, MODE_NEWFILE);
  1990.          if (fh)
  1991.          {
  1992.             mywin->Flags &= ~SIZEGADGET;
  1993.             reg = GetAPen (winrp);
  1994.             SetAPen (winrp, 0);
  1995.             saveiff ();
  1996.             Close (fh);
  1997.             BltBitMapRastPort (destbm, 0, 0, winrp, leftoff, topoff, innerwidth, innerheight, ABNC | ABC);
  1998.             SetAPen (winrp, reg);
  1999.             mywin->Flags |= SIZEGADGET;
  2000.          }
  2001.          else
  2002.          {
  2003.             error ("Can't create '%s'.", iffname);
  2004.          }
  2005.          CurrentDir (olddirlock);
  2006.          UnLock (dirlock);
  2007.       }
  2008.       else
  2009.       {
  2010.          error ("Can't lock '%s'.", iffpath);
  2011.       }
  2012.    }
  2013.    return TRUE;
  2014. }
  2015.  
  2016. BOOL coordsFunc ()
  2017. {
  2018.    if (!coords && (item->Flags & CHECKED))
  2019.    {
  2020.       coords = TRUE;
  2021.    }
  2022.    else if (coords && !(item->Flags & CHECKED))
  2023.    {
  2024.       coords = FALSE;
  2025.    }
  2026.    else
  2027.    {
  2028.       return TRUE;  // nothing changed
  2029.    }
  2030.    return reopenwin ();
  2031. }
  2032.  
  2033. BOOL gridFunc ()
  2034. {
  2035.    grid = (item->Flags & CHECKED) != 0;
  2036.    setupgrid ();
  2037.    return TRUE;
  2038. }
  2039.  
  2040. BOOL showrgbFunc ()
  2041. {
  2042.    if (!showrgb && (item->Flags & CHECKED))
  2043.    {
  2044.       showrgb = TRUE;
  2045.    }
  2046.    else if (showrgb && !(item->Flags & CHECKED))
  2047.    {
  2048.       showrgb = FALSE;
  2049.    }
  2050.    else
  2051.    {
  2052.       return TRUE;  // nothing changed
  2053.    }
  2054.    return reopenwin ();
  2055. }
  2056.  
  2057. BOOL enableFunc ()
  2058. {
  2059.    if (item->Flags & CHECKED)
  2060.    {
  2061.       ActivateCxObj (broker, 1);
  2062.       enable = TRUE;
  2063.    }
  2064.    else if (!(item->Flags & CHECKED))
  2065.    {
  2066.       ActivateCxObj (broker, 0);
  2067.       enable = FALSE;
  2068.    }
  2069.    return TRUE;
  2070. }
  2071.  
  2072. BOOL hideoncloseFunc ()
  2073. {
  2074.    hideonclose = (item->Flags & CHECKED) != 0;
  2075.    return TRUE;
  2076. }
  2077.  
  2078. BOOL hideFunc ()
  2079. {
  2080.    hidewindow ();
  2081.    jump = TRUE;
  2082.    return TRUE;
  2083. }
  2084.  
  2085. BOOL QuitFunc ()
  2086. {
  2087.    return FALSE;
  2088. }
  2089.  
  2090. BOOL argbool (char **argv, char *name, BOOL def)
  2091. {
  2092.    char *value = (char *) FindToolType ((UBYTE **) argv, name);
  2093.    if (value)
  2094.    {
  2095.       if ((MatchToolValue (value, "YES")) || (MatchToolValue (value, "ON"))) return TRUE;
  2096.       if ((MatchToolValue (value, "OFF")) || (MatchToolValue (value, "NO"))) return FALSE;
  2097.    }
  2098.    return def;
  2099. }
  2100.  
  2101. LONG argint (char **argv, UBYTE *name, LONG def)
  2102. {
  2103.  LONG returnvalue;
  2104.  
  2105.    APTR value = FindToolType ((UBYTE **) argv, name);
  2106.    if (value)
  2107.    {
  2108.       if (StrToLong ((UBYTE *) value, &returnvalue))
  2109.       {
  2110.          return returnvalue;
  2111.       }
  2112.    }
  2113.    return def;
  2114. }
  2115.  
  2116. void argstring (char *result, char **argv, char *name, size_t size = 50)
  2117. {
  2118.    char *value = FindToolType ((UBYTE **) argv, name);
  2119.    if (value)
  2120.    {
  2121.       strncpy (result, value, size);
  2122.    }
  2123. }
  2124.  
  2125. void readargs ()
  2126. {
  2127.  // first time always the tooltypes will be evaluated
  2128.  // if we started from Cli the tooltypes can be overloaded
  2129.  char **argv;
  2130.  struct DiskObject *programicon;
  2131.  struct RDArgs * rdargs;
  2132.  struct DrawInfo *drawinfo;
  2133.  LONG a[19];
  2134.  long *args = a;
  2135.  
  2136.    wintop = scr->RastPort.TxHeight + (UWORD) scr->WBorTop + 1;
  2137.    // make window as square as possible
  2138.    drawinfo = GetScreenDrawInfo (scr);
  2139.    if (drawinfo)
  2140.    {
  2141.       innerheight = innerwidth * drawinfo->dri_Resolution.X / drawinfo->dri_Resolution.Y;
  2142.       FreeScreenDrawInfo (scr, drawinfo);
  2143.    }
  2144.    if (Cli ())
  2145.    {
  2146.       GetProgramName (programname, 108);
  2147.    }
  2148.    else
  2149.    {
  2150.       strcpy (programname, thistask->tc_Node.ln_Name);
  2151.    }
  2152.    IconBase = OpenLibrary ("icon.library", 37);
  2153.    if (IconBase)
  2154.    {
  2155.       programicon = GetDiskObject (programname);
  2156.       if (programicon)
  2157.       {
  2158.          argv = programicon->do_ToolTypes;
  2159.          newbroker.nb_Pri = argint (argv, "CX_Priority", newbroker.nb_Pri);
  2160.          fast = argbool (argv, "Fast", fast);
  2161.          maxscalefac = argint (argv, "MaxScaleFactor", maxscalefac);
  2162.          scalefac = argint (argv, "ScaleFactor", scalefac);
  2163.          winleft = argint (argv, "WinLeft", winleft);
  2164.          wintop = argint (argv, "WinTop", wintop);
  2165.          innerheight = argint (argv, "WinHeight", innerheight);
  2166.          innerwidth = argint (argv, "WinWidth", innerwidth);
  2167.          coords = argbool (argv, "Coordinates", coords);
  2168.          crosshair = argbool (argv, "Crosshair", crosshair);
  2169.          argstring (setoriginkey, argv, "SetOriginKey");
  2170.          argstring (resetoriginkey, argv, "ResetOriginKey");
  2171.          fixed = argbool (argv, "Fixed", fixed);
  2172.          argstring (showhidekey, argv, "ShowHideKey");
  2173.          hide = argbool (argv, "Iconify", hide);
  2174.          hideonclose = argbool (argv, "IconifyOnClose", hideonclose);
  2175.          grid = argbool (argv, "Grid", grid);
  2176.          showrgb = argbool (argv, "ShowRGB", showrgb);
  2177.          argstring (iffpath, argv, "IFFFile", 255);
  2178.          FreeDiskObject (programicon);
  2179.       }
  2180.       CloseLibrary (IconBase);
  2181.    }
  2182.    if (Cli ())
  2183.    {
  2184.       memset (args, '\0', 19 * sizeof (LONG));
  2185.       args[1] = fast;
  2186.       args[8] = coords;
  2187.       args[9] = crosshair;
  2188.       args[12] = fixed;
  2189.       args[14] = hide;
  2190.       args[15] = hideonclose;
  2191.       args[16] = grid;
  2192.       args[17] = showrgb;
  2193.       rdargs = ReadArgs (Template, args, NULL);
  2194.       if (rdargs)
  2195.       {
  2196.          if (*args) newbroker.nb_Pri = *args;
  2197.          args++;
  2198.          fast = *args++;
  2199.          if (*args) maxscalefac = *(LONG *) *args;
  2200.          if (*++args) scalefac = *(LONG *) *args;
  2201.          if (*++args) winleft = *(LONG *) *args;
  2202.          if (*++args) wintop = *(LONG *) *args;
  2203.          if (*++args) innerwidth = *(LONG *) *args;
  2204.          if (*++args) innerheight = *(LONG *) *args;
  2205.          args++;
  2206.          coords = *args++;
  2207.          crosshair = *args++;
  2208.          if (*args) strncpy (setoriginkey, (char *) *args, 50);
  2209.          if (*++args) strncpy (resetoriginkey, (char *) *args, 50);
  2210.          args++;
  2211.          fixed = *args++;
  2212.          if (*args) strncpy (showhidekey, (char *) *args, 50);
  2213.          args++;
  2214.          hide = *args++;
  2215.          hideonclose = *args++;
  2216.          grid = *args++;
  2217.          showrgb = *args++;
  2218.          if (*args) strncpy (iffpath, (char *) *args, 255);
  2219.          FreeArgs (rdargs);
  2220.       }
  2221.    }
  2222.    if (maxscalefac < 5) maxscalefac = 5;
  2223.    // not lower than innerheight or innerwidth
  2224.    // otherwise 'innerheight / scalefac' or 'innerwidth / scalefac'
  2225.    // can go to 0 -> 'AllocBitMap ()' failed
  2226.    if (maxscalefac > MINHEIGHT) maxscalefac = MINHEIGHT;
  2227.    if (scalefac > maxscalefac) scalefac = maxscalefac;
  2228.    if (innerheight < MINHEIGHT) innerheight = MINHEIGHT;
  2229.    if (innerwidth < MINWIDTH) innerwidth = MINWIDTH;
  2230.    
  2231.    char *str;
  2232.    str = strrchr (iffpath, '/');
  2233.    if (str)
  2234.    {
  2235.       strncpy (iffname, str + 1, 108);
  2236.       *str = '\0';
  2237.    }
  2238.    else if ((str = strrchr (iffpath, ':')) != 0)
  2239.    {
  2240.       strncpy (iffname, ++str, 108);
  2241.       *str = '\0';
  2242.    }
  2243.    else
  2244.    {
  2245.       strncpy (iffname, iffpath, 108);
  2246.       iffpath[0] = '\0';
  2247.    }
  2248. }
  2249.  
  2250. void main ()
  2251. {
  2252.    if ((CxBase = OpenLibrary ("commodities.library", 37)) != 0)
  2253.    {
  2254.       if ((GfxBase = (struct GfxBase *) OpenLibrary ("graphics.library", 39)) != 0)
  2255.       {
  2256.          if ((GadToolsBase = OpenLibrary ("gadtools.library", 37)) != 0)
  2257.          {
  2258.             if ((WorkbenchBase = OpenLibrary ("workbench.library", 37)) != 0)
  2259.             {
  2260.                if ((AslBase = OpenLibrary ("asl.library", 37)) != 0)
  2261.                {
  2262.                   CyberGfxBase = OpenLibrary ("cybergraphics.library", 40);
  2263.                   InitRastPort (&destrp);
  2264.                   SetAPen (&destrp, 0);
  2265.                   InitRastPort (&maskrp);
  2266.                   SetDrMd (&maskrp, COMPLEMENT);
  2267.                   thistask = FindTask (NULL);
  2268.                   if ((topazfont = OpenFont (&topaz_attr)) != 0)
  2269.                   {
  2270.                      if (!setupscreen (NULL))
  2271.                      {
  2272.                         readargs ();
  2273.                         getoffsets ();
  2274.                         try
  2275.                         {
  2276.                            if (!hide)
  2277.                            {
  2278.                               if (!openwin ()) throw 1;
  2279.                               if (allocbm ()) throw 2;
  2280.                            }
  2281.                            if ((timesig = AllocSignal (-1L)) != -1)
  2282.                            {
  2283.                               if ((showhidesig = AllocSignal (-1L)) != -1)
  2284.                               {
  2285.                                  if (initbroker ())
  2286.                                  {
  2287.                                     processmsg ();
  2288.                                     DeleteCxObjAll (broker);
  2289.                                     DeleteMsgPort (broker_mp);
  2290.                                  }
  2291.                                  FreeSignal (showhidesig);
  2292.                               }
  2293.                               FreeSignal (timesig);
  2294.                            }
  2295.                            else
  2296.                            {
  2297.                               error ("Can't allocate signal");
  2298.                            }
  2299.                         }  // try
  2300.                         catch (int) { }
  2301.                         closewin ();
  2302.                         CloseDownScreen ();
  2303.                         freeappicon ();
  2304.                      }
  2305.                      CloseFont (topazfont);
  2306.                      if (screenfont)
  2307.                      {
  2308.                         CloseFont (screenfont);
  2309.                      }
  2310.                   }
  2311.                   else
  2312.                   {
  2313.                      error ("Can't open Topaz.font");
  2314.                   }
  2315.                   if (CyberGfxBase)
  2316.                   {
  2317.                      CloseLibrary (CyberGfxBase);
  2318.                   }
  2319.                   CloseLibrary (AslBase);
  2320.                }
  2321.                else
  2322.                {
  2323.                   error ("Can't open '%s' version %ld or higher.", "asl.library", 37L);
  2324.                }
  2325.                CloseLibrary (WorkbenchBase);
  2326.             }
  2327.             else
  2328.             {
  2329.                error ("Can't open '%s' version %ld or higher.", "workbench.library", 37L);
  2330.             }
  2331.             CloseLibrary (GadToolsBase);
  2332.          }
  2333.          else
  2334.          {
  2335.             error ("Can't open '%s' version %ld or higher.", "gadtools.library", 37L);
  2336.          }
  2337.          CloseLibrary ((struct Library *) GfxBase);
  2338.       }
  2339.       else
  2340.       {
  2341.          error ("Can't open '%s' version %ld or higher.", "graphics.library", 39L);
  2342.       }
  2343.       CloseLibrary (CxBase);
  2344.    }
  2345.    else
  2346.    {
  2347.       error ("Can't open '%s' version %ld or higher.", "commodities.library", 37L);
  2348.    }
  2349. }
  2350.  
  2351.